#include <string.h>
#include <stdio.h>
#include <stdbool.h>
#include <unistd.h>

#include "lwip/init.h"
#include "lwip/pbuf.h"
#include "lwip/ip.h"
#include "lwip/tcp.h"
#include "lwip/tcpip.h"
#include "lwip/altcp.h"
#include "lwip/altcp_tcp.h"
#include "lwip/err.h"
#include "lwip/timeouts.h"
#include "lwip/netif.h"
#include "lwip/init.h"
#include "netif/tapif.h"


#include "lwip/altcp_tls.h"

#define SERVER_CERT_PEM \
    "-----BEGIN CERTIFICATE-----\r\n" \
    "MIIDjjCCAnagAwIBAgIBAjANBgkqhkiG9w0BAQsFADBiMQswCQYDVQQGEwJYWDEL\r\n" \
    "MAkGA1UECAwCWFgxFDASBgNVBAoMC2NlcnRpZmljYXRlMQ8wDQYDVQQLDAZ0ZXN0\r\n" \
    "aW4xHzAdBgNVBAMMFmNlcnRpZmljYXRlLnRlc3Rpbi5jb20wHhcNMjQwNDI1MTMw\r\n" \
    "MTAwWhcNMzQwNDIzMTMwMTAwWjBkMQswCQYDVQQGEwJYWDELMAkGA1UECAwCWFgx\r\n" \
    "FDASBgNVBAoMC2NlcnRpZmljYXRlMRAwDgYDVQQLDAd0ZXN0ZW5kMSAwHgYDVQQD\r\n" \
    "DBdjZXJ0aWZpY2F0ZS50ZXN0ZW5kLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP\r\n" \
    "ADCCAQoCggEBAK9T/dT9fLQZX2lqXHg9GxwEv++WVXzTyEnpEpLx0MOpBiCEiSqF\r\n" \
    "IAxlNaW3Mzon3M/Ntocan32auELK5SlYK3vhItiGlzVvZrg6ujxVYiKFGk9DUQaC\r\n" \
    "NZny1KEoMu2aGH57BgzAdrBflETcrKfBN9LVqMctG/FNp+2fll1V8hWmiIiIGlnv\r\n" \
    "dAUAGFnEjp3G+7pMNtwNOOpMTGMeOazIS9RrY/Iv4lKCWD8xk0E41hIUhp7OSlx0\r\n" \
    "VroUzHpdbiJXPnrUgwF1UERzogjupahAlr6U+woQVDw/6Iba69lBIhuh10t06X0g\r\n" \
    "QZngQdwwlPPGHXsZoIDsET8yWxzsFimH3BMCAwEAAaNNMEswCQYDVR0TBAIwADAd\r\n" \
    "BgNVHQ4EFgQU048bICa5uwCw9sd8ODfS1iH948MwHwYDVR0jBBgwFoAU4GCTfzm7\r\n" \
    "BSEZRBCwwClkora7IxIwDQYJKoZIhvcNAQELBQADggEBAASc7YWiddHFPhbCnG96\r\n" \
    "B/bx5p8oXh3X0RiUwIVRbsjPTg/3U2Kykfg75BbWkycGBJD7HnTKwRmr/Tv7LUpO\r\n" \
    "p0TCVMxkbER/idz4+pc88b/LwUfc/m0MEjSdtrY/CAKwMus3WrzNUUP+uwxymhxf\r\n" \
    "R1NveWAO/pDwvS13opQqmB9wjfq6ytgaQRh+IsswqAbv3qENjhm01j9N2fjxVnvF\r\n" \
    "pl7clPu6dzniIrUzh3nJHeWXkOmomxgVusMXwAla7atyFbOn/7Mg3a+5NSKqj4Ns\r\n" \
    "7HNJLQ8CvnrUEE7b2HW0TxGN0uJNBDE99iTwDs+kLyE7iyPyICDuA8teTLgt5I2Y\r\n" \
    "SKk=\r\n" \
    "-----END CERTIFICATE-----"

#define SERVER_KEY_PEM \
    "-----BEGIN PRIVATE KEY-----\r\n" \
    "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCvU/3U/Xy0GV9p\r\n" \
    "alx4PRscBL/vllV808hJ6RKS8dDDqQYghIkqhSAMZTWltzM6J9zPzbaHGp99mrhC\r\n" \
    "yuUpWCt74SLYhpc1b2a4Oro8VWIihRpPQ1EGgjWZ8tShKDLtmhh+ewYMwHawX5RE\r\n" \
    "3KynwTfS1ajHLRvxTaftn5ZdVfIVpoiIiBpZ73QFABhZxI6dxvu6TDbcDTjqTExj\r\n" \
    "HjmsyEvUa2PyL+JSglg/MZNBONYSFIaezkpcdFa6FMx6XW4iVz561IMBdVBEc6II\r\n" \
    "7qWoQJa+lPsKEFQ8P+iG2uvZQSIboddLdOl9IEGZ4EHcMJTzxh17GaCA7BE/Mlsc\r\n" \
    "7BYph9wTAgMBAAECggEAVHY2ZGpfLlXAyIQ0Grp5OlSxcAZwlWti4/QzffWfN/rP\r\n" \
    "mE+w0nqCV2ZUY0ovk/cLIVJ8+XXiWnx0Ar1Ci1nNzOZGxp+D7XqGtf6YpCMP3QhZ\r\n" \
    "BdEskeGdV9YLB73ZVuwym4/BeNgo9Ut+HnReeowSy+8g2R7KhML/wHHuWnViY3nj\r\n" \
    "hRnd2tit+y8MQcz8fOcgTT6Uuk6XeEutDMN7FoiLIyNX+mKWtsJbeLFWpHVm9ZM/\r\n" \
    "R7wa4T/NeFVhfJbJ9YTrZDeLX2dm+F6ynYTJXZvl5KX/pDtQDMkCjadtDOVoc3S1\r\n" \
    "LYEXAq6F7rcw+S8T0sDrZxGOUw8xAWUmUlL2oSKpOQKBgQDIrom9u3bdJrzglRDP\r\n" \
    "QuA/dx4IFuZOUaVYPG3NgG/XGtx1yKF2p+XqSWI1wb4fe59S6oJj9KhUKpEZYFoW\r\n" \
    "c9zgVtl9NsU1gtXfSAuy0pAwTOTdFDzO+b9IIg6zGrh0UT83Ett/zoU2OZWej7xk\r\n" \
    "ZxCLTZ7lXav+OwquIMMsjFW3KQKBgQDfqFNOwGrWrPyLQGBS9uz4IAOysY0Nydd3\r\n" \
    "9et7ivzgVAj2p3pb8OuCuMhHmCMd7ocIrijCtF5ppNQ9UhkNhq6crlA9L5jRVLd4\r\n" \
    "GJTjYnnnA2qNGklu51Q/5XHPMTndXmbrE+jq1VLmx7pGd/XEy83gDXNsB4sLsYgH\r\n" \
    "OLZd+bRM2wKBgE0H0g9mGeYhrHZ4QY+NGA7EZl6si5KcfF82Mt+i4UssIFuFu5SU\r\n" \
    "NgiMSopf596l0S4+nfZIPySvgiq/dVUQ/EOQksMhdulnYzjlqrflYztnCKJj1kOM\r\n" \
    "UgQaLpJJO2xKk31MW7zfRPrfd7L5cVMIzKzsCoX4QsC/YQYdxU0gQPahAoGAenii\r\n" \
    "/bmyB1H8jIg49tVOF+T4AW7mTYmcWo0oYKNQK8r4iZBWGWiInjFvQn0VpbtK6D7u\r\n" \
    "BQhdtr3Slq2RGG4KybNOLuMUbHRWbwYO6aCwHgcp3pBpa7hy0vZiZtGO3SBnfQyO\r\n" \
    "+6DK36K45wOjahsr5ieXb62Fv2Z8lW/BtR4aVAcCgYEAicMLTwUle3fprqZy/Bwr\r\n" \
    "yoGhy+CaKyBWDwF2/JBMFzze9LiOqHkjW4zps4RBaHvRv84AALX0c68HUEuXZUWj\r\n" \
    "zwS7ekmeex/ZRkHXaFTKnywwOraGSJAlcwAwlMNLCrkZn9wm79fcuaRoBCCYpCZL\r\n" \
    "5U2HZPvTIa7Iry46elKZq3g=\r\n" \
    "-----END PRIVATE KEY-----"

static struct netif g_netif; // 全局网络接口

static bool send = false;


static void tls_server_err(void *arg, err_t err)
{
    (void)arg;
    printf("TLS服务器错误: %d, %s\n", err, lwip_strerr(err));
}


static err_t tls_server_recv(void *arg, struct altcp_pcb *pcb, struct pbuf *p, err_t err)
{
    (void)arg;
    (void)err;

    if (p == NULL) {
        printf("TLS服务器接收数据失败: %d\n", err);
        altcp_close(pcb);
        return ERR_OK;
    }

    printf("Received %d bytes: %s\n", p->len, (char *)p->payload);
    
    // 回显接收到的数据
    altcp_write(pcb, p->payload, p->len, TCP_WRITE_FLAG_COPY);
    pbuf_free(p);
    return ERR_OK;
}

static err_t tls_server_sent(void *arg, struct altcp_pcb *pcb, u16_t len)
{
    (void)arg;
    (void)pcb;
    (void)len;
    if (send == false) {
        char *data = "Hello, Client!";
        uint16_t len = strlen(data);
        uint16_t maxLen = altcp_sndbuf(pcb);
        if (len > maxLen) {
            len = maxLen;
        }
        err_t err = altcp_write(pcb, data, len, TCP_WRITE_FLAG_COPY);
        if (err != ERR_OK) {
            printf("Failed to send data to client: %d\n", err);
            return err;
        }
        send = true;
        return err;
    }
    return ERR_OK;
}

static err_t tls_server_accept(void *arg, struct altcp_pcb *pcb, err_t err)
{
    (void)arg;

    if (err != ERR_OK) {
        printf("Failed to accept TLS server connection: %d\n", err);
        return err;
    }

    altcp_recv(pcb, tls_server_recv);
    altcp_sent(pcb, tls_server_sent);
    altcp_err(pcb, tls_server_err);
    return ERR_OK;
}

err_t tls_server_init(void)
{
    struct altcp_tls_config *config;
    struct altcp_pcb *pcb;

    // 创建TLS服务器配置, 加载证书和私钥
    config = altcp_tls_create_config_server_privkey_cert(SERVER_KEY_PEM, strlen(SERVER_KEY_PEM) + 1, NULL, 0,
        SERVER_CERT_PEM, strlen(SERVER_CERT_PEM) + 1);
    if (config == NULL) {
        printf("Failed to create TLS server config\n");
        return ERR_MEM;
    }

    // 创建TLS服务器PCB
    pcb = altcp_tls_new(config, IPADDR_TYPE_ANY);
    if (pcb == NULL) {
        printf("Failed to create TLS server pcb\n");
        altcp_tls_free_config(config);
        return ERR_MEM;
    }
    printf("TLS服务器配置成功\n");

    err_t err = altcp_bind(pcb, IP_ADDR_ANY, 8888);
    if (err != ERR_OK) {
        printf("Failed to bind port: %d\n", err);
        altcp_tls_free_config(config);
        return err;
    }

    // 启动TLS服务器
    pcb = altcp_listen(pcb);
    if (pcb == NULL) {
        printf("Failed to listen: %d\n", err);
        altcp_tls_free_config(config);
        return ERR_MEM;
    }

    printf("TLS服务器启动成功\n");

    // 设置回调函数
    altcp_accept(pcb, tls_server_accept);

    printf("TLS server listen on port 8888\n");
    return ERR_OK;
}

int main(void)
{
    ip4_addr_t ipaddr;
    ip4_addr_t netmask;
    ip4_addr_t gw;

    /* 初始化LWIP */
    tcpip_init(NULL, NULL);
    printf("LWIP初始化完成\n");

    IP4_ADDR(&ipaddr, 192, 168, 100, 2);
    IP4_ADDR(&netmask, 255, 255, 255, 0);
    IP4_ADDR(&gw, 192, 168, 100, 1);


    /* 配置网络接口 */
    if (netif_add(&g_netif, &ipaddr, &netmask, &gw, NULL, tapif_init, tcpip_input) == NULL) {
        printf("Failed to configure network interface\n");
        return -1;
    }

    /* 启动网络接口 */
    netif_set_default(&g_netif);
    netif_set_up(&g_netif);
    printf("网络接口启动完成\n");

    err_t err = tls_server_init();
    if (err != ERR_OK) {
        printf("Failed to initialize TLS server: %d\n", err);
        return -1;
    }
    printf("TLS服务器初始化完成\n");

    while (1) {
        sys_check_timeouts();
        usleep(1000);
    }
    
}